package comgame.components;

import com.almasb.fxgl.animation.Animation;
import com.almasb.fxgl.animation.Interpolators;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.component.Component;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point2D;
import javafx.scene.effect.ColorAdjust;
import javafx.util.Duration;

import static com.almasb.fxgl.dsl.FXGL.tpf;

/**
 * FXGL 17.3 纯代码动画组件
 * 包含待机、攻击、受伤和死亡动画
 */
public class AnimationComponent extends Component {

    // 动画状态枚举，表示实体当前的动画状态
    public enum AnimState { IDLE, ATTACKING, HURT, DEAD }
    private AnimState currentState = AnimState.IDLE; // 当前动画状态

    // 待机动画相关字段
    private double idleTime = 0.0; // 记录待机动画时间
    private Point2D originalPosition; // 实体原始位置
    private double originalRotation; // 实体原始旋转角度

    // 攻击动画相关字段
    private Animation<?> attackAnimation; // 攻击动画对象
    private Point2D attackStartPosition; // 攻击开始位置

    // 受伤动画相关字段
    private double hurtTime = 0.0; // 记录受伤动画时间
    private ColorAdjust hurtEffect; // 颜色调整效果，用于闪红

    // 死亡动画相关字段
    private Animation<?> deathAnimation; // 死亡动画对象

    /**
     * 当组件被添加到实体时调用
     * 初始化原始位置、旋转和受伤效果
     */
    @Override
    public void onAdded() {
        // 保存原始位置和旋转
        originalPosition = entity.getPosition();
        originalRotation = entity.getRotation();
        attackStartPosition = originalPosition;

        // 初始化受伤效果
        hurtEffect = new ColorAdjust();
        hurtEffect.setHue(0);
        entity.getViewComponent().getChildren().forEach(node -> node.setEffect(hurtEffect));
    }

    /**
     * 每帧更新方法
     * 根据当前状态更新相应的动画
     * @param tpf 每帧时间间隔
     */
    @Override
    public void onUpdate(double tpf) {
        switch (currentState) {
            case IDLE:
                updateIdleAnimation(tpf); // 更新待机动画
                break;
            case ATTACKING:
                // 攻击动画由FXGL动画系统驱动，无需额外更新
                break;
            case HURT:
                updateHurtAnimation(tpf); // 更新受伤动画
                break;
            case DEAD:
                playDie(); // 播放死亡动画
                break;
        }
    }

    /**
     * 更新待机动画（小幅度左右抖动）
     * @param tpf 每帧时间间隔
     */
    private void updateIdleAnimation(double tpf) {
        // 检查实体是否仍然存在
        if (entity == null || !entity.isActive()) {
            return;
        }
        
        idleTime += tpf * 5;
        // 使用正弦函数创建抖动效果（左右移动约2像素）
        double offset = Math.sin(idleTime) * 2;
        entity.setX(originalPosition.getX() + offset);
    }

    /**
     * 更新受伤动画（闪红效果）
     * @param tpf 每帧时间间隔
     */
    private void updateHurtAnimation(double tpf) {
        // 检查实体是否仍然存在
        if (entity == null || !entity.isActive()) {
            return;
        }
        
        hurtTime += tpf * 10; // 保持原速度

        // 增强闪红效果：更亮的红色和闪烁效果
        double intensity = Math.abs(Math.sin(hurtTime)) * 0.9;
        hurtEffect.setBrightness(intensity * 0.5); // 增加亮度
        hurtEffect.setSaturation(intensity); // 增加饱和度
        hurtEffect.setHue(-intensity * 0.8); // 更强烈的红色偏移

        // 延长闪红时间到2秒
        if (hurtTime >= 2.0) {
            // 重置颜色效果
            hurtEffect.setHue(0);
            hurtEffect.setBrightness(0);
            hurtEffect.setSaturation(0);
            currentState = AnimState.IDLE; // 返回待机状态
            hurtTime = 0; // 重置计时器
        }
    }

    /**
     * 播放待机动画
     */
    public void playIdle() {
        if (currentState == AnimState.DEAD) return; // 如果已死亡，不执行

        // 检查实体是否仍然存在
        if (entity == null || !entity.isActive()) {
            return;
        }

        currentState = AnimState.IDLE;
        entity.setPosition(originalPosition); // 回到原始位置
        entity.setRotation(originalRotation); // 回到原始旋转
    }

    /**
     * 播放攻击动画
     * @param target 攻击目标位置
     */
    public void playAttack(Point2D target) {
        // 只有在待机状态下才能发起攻击，防止动画被覆盖
        if (currentState != AnimState.IDLE) {
            System.out.println("攻击被阻止：当前状态为 " + currentState);
            return;
        }

        // 检查实体是否仍然存在
        if (entity == null || !entity.isActive()) {
            return;
        }

        currentState = AnimState.ATTACKING;
        attackStartPosition = entity.getPosition(); // 记录攻击起始位置

        // 1. 计算攻击方向
        Point2D attackDirection = target.subtract(attackStartPosition).normalize();

        // 2. 计算攻击位置：冲到敌方身前但不重合
        // 计算到目标的距离
        double distanceToTarget = attackStartPosition.distance(target);
        
        // 考虑双方碰撞箱大小，确保不重合
        // 攻击者碰撞箱半径（假设为30像素）
        double attackerRadius = 30;
        // 目标碰撞箱半径（假设为30像素）
        double targetRadius = 30;
        // 最小安全距离（两个碰撞箱之间的间隙）- 减小这个值让攻击者更接近
        double safetyGap = 2; // 从5减少到2，让攻击者更接近敌方
        
        // 计算攻击距离：冲到敌方身前，但保持安全距离
        double attackDistance = distanceToTarget - (attackerRadius + targetRadius + safetyGap);
        
        // 确保攻击距离合理（至少移动10像素，最多不超过原距离的90%）
        attackDistance = Math.max(attackDistance, 10);
        attackDistance = Math.min(attackDistance, distanceToTarget * 0.9); // 从0.8增加到0.9，允许更接近
        
        Point2D attackPosition = attackStartPosition.add(attackDirection.multiply(attackDistance));

        // 3. 攻击动画序列
        FXGL.animationBuilder()
                .duration(Duration.seconds(60*tpf()))
                .translate(entity)
                .from(originalPosition)
                .to(attackPosition) // 冲到敌方身前但不重合
                .buildAndPlay();

        // 创建旋转动画
        FXGL.animationBuilder()
                .delay(Duration.seconds(60*tpf()))
                .duration(Duration.seconds(30*tpf()))
                .rotate(entity)
                .to(45.0)
                .buildAndPlay();

        FXGL.animationBuilder()
                .delay(Duration.seconds(100*tpf()))
                .duration(Duration.seconds(20*tpf()))
                .rotate(entity)
                .to(originalRotation)
                .buildAndPlay();

        FXGL.animationBuilder()
                .delay(Duration.seconds(120*tpf()))
                .duration(Duration.seconds(30*tpf()))
                .translate(entity)
                .from(attackPosition) // 从攻击位置返回
                .to(originalPosition)
                .buildAndPlay();

        FXGL.getGameTimer().runOnceAfter(() -> {
            // 检查实体是否仍然存在
            if (entity != null && entity.isActive()) {
                playIdle();
            }
        }, Duration.seconds(170*tpf()));
    }

    /**
     * 播放受伤动画（闪红效果）
     */
    public void playHurt() {
        if (currentState == AnimState.DEAD) return; // 如果已死亡，不执行

        currentState = AnimState.HURT;
        hurtTime = 0.0; // 重置受伤时间
    }

    /**
     * 播放死亡动画
     */
    public void playDie() {
        if (currentState == AnimState.DEAD) return; // 如果已死亡，不重复播放

        currentState = AnimState.DEAD;

        // 停止所有现有动画
        if (attackAnimation != null) {
            attackAnimation.stop();
        }

        // 保存当前位置作为死亡动画起点
        Point2D deathStartPosition = entity.getPosition();
        double deathStartRotation = entity.getRotation();
        double deathStartOpacity = entity.getOpacity();

        // 创建虚拟属性用于驱动进度
        SimpleDoubleProperty progress = new SimpleDoubleProperty(0);

        // 设置进度监听器
        progress.addListener((obs, oldValue, newValue) -> {
            // 检查实体是否仍然存在
            if (entity == null || !entity.isActive()) {
                return; // 如果实体不存在，直接返回
            }
            
            double ratio = newValue.doubleValue();
            // 旋转
            entity.setRotation(deathStartRotation + ratio * 360);
            // 下沉
            entity.setY(deathStartPosition.getY() + ratio * 100);
            // 淡出
            entity.setOpacity(deathStartOpacity * (1 - ratio));

            // 增加缩放效果
            entity.setScaleX(1.0 - ratio * 0.5);
            entity.setScaleY(1.0 - ratio * 0.5);
        });

        // 死亡动画：旋转并下沉
        FXGL.animationBuilder()
                .duration(Duration.seconds(1.5))
                .interpolator(Interpolators.EXPONENTIAL.EASE_OUT())
                .animate(progress)
                .from(0.0)
                .to(1.0)
                .buildAndPlay();

        FXGL.getGameTimer().runOnceAfter(() -> {
            // 检查实体是否仍然存在
            if (entity != null && entity.isActive()) {
                entity.removeFromWorld(); // 从世界中移除实体
            }
        }, Duration.seconds(1.5));
    }

    /**
     * 重置原始位置（当玩家移动时调用）
     * @param newPosition 新的原始位置
     */
    public void resetOriginalPosition(Point2D newPosition) {
        this.originalPosition = newPosition;
    }

    /**
     * 获取当前动画状态
     * @return 当前动画状态
     */
    public AnimState getCurrentState() {
        return currentState;
    }
}